home *** CD-ROM | disk | FTP | other *** search
/ Audio 4.94 - Over 11,000 Files / audio-11000.iso / mac / speech / spchmngr.hqx / Speech Manager demo ƒ / Speech Manager demo.c next >
Encoding:
C/C++ Source or Header  |  1993-08-17  |  7.2 KB  |  392 lines

  1. /*
  2.  * A simple program for messing around with the new Speech Manager.
  3.  * By Alex Kourakos
  4.  * kourakos@ncsc.org
  5.  */
  6.  
  7. #include    <Speech.h>
  8. #include    <Errors.h>
  9. #include    <GestaltEqu.h>
  10. #include    <FixMath.h>
  11. #include    <pascal.h>
  12.  
  13. #include    <stdio.h>
  14. #include    <stdlib.h>
  15. #include    <string.h>
  16.  
  17.  
  18. /*
  19.  * Globals.
  20.  */
  21.  
  22. SpeechChannel        gSpeechChannel = nil;    // The current speech channel.
  23. VoiceDescription    gVoiceDescription;        // A record containing useful (?) information.
  24. short                gCountVoices,            // The number of voices available.
  25.                     gCurrentVoiceIndex;        // The number of the current voice.
  26.  
  27. char                gSayThis[255];            // The string that we want to say.
  28.  
  29. Boolean                gDone = false;            // Are we through with this fine program?
  30.  
  31.  
  32. /*
  33.  * Function prototypes.
  34.  */
  35.  
  36. void main(void);
  37. void TestForSpeechManager(void);
  38. void Initialize(void);
  39. void ReadLine(void);
  40. void LoadVoice(short);
  41. void HandleError(OSErr);
  42. void PrintHelp(void);
  43.  
  44.  
  45. /*
  46.  * Main.
  47.  */
  48.  
  49. void main(void) {
  50.     OSErr    err;
  51.  
  52.     TestForSpeechManager();
  53.  
  54.     Initialize();
  55.  
  56.     while( !gDone )
  57.         ReadLine();
  58.  
  59.     /* 
  60.      * Loop until quiet so that we don't cut the voice off.
  61.      */
  62.  
  63.     while( SpeechBusy() )
  64.         ;
  65.  
  66.     /*
  67.      * Let's be polite and kill the speech channel as we leave.
  68.      */
  69.  
  70.     if( gSpeechChannel != nil ) {
  71.         err = DisposeSpeechChannel(gSpeechChannel);
  72.         if( err != noErr) HandleError(err);
  73.         }
  74.  
  75.     ExitToShell();
  76.     }
  77.  
  78.  
  79. /*
  80.  * Use Gestalt to see if the Speech Manager is around.
  81.  */
  82.  
  83. void TestForSpeechManager(void) {
  84.     long    result;
  85.     OSErr    err;
  86.  
  87.     err = Gestalt(gestaltSpeechAttr,&result);
  88.  
  89.     if( err != noErr )
  90.         HandleError(err);
  91.  
  92.     if( !(result & (1L << gestaltSpeechMgrPresent)) ) {
  93.         fprintf(stderr,"Sorry, you do not have the Speech Manager installed.\n");
  94.         exit(EXIT_FAILURE);
  95.         }
  96.     }
  97.  
  98.  
  99. /*
  100.  * Initialize the voice, etc.
  101.  */
  102.  
  103. void Initialize(void) {
  104.     OSErr    err;
  105.  
  106.     /*
  107.      * Just in case somebody types "!!" right away.
  108.      */
  109.  
  110.     sprintf(gSayThis,"The quick brown fox jumps over the lazy dog.\n");
  111.  
  112.     /*
  113.      * Find out how many voices we have.
  114.      */
  115.  
  116.     err = CountVoices(&gCountVoices);
  117.     if( err != noErr) HandleError(err);
  118.  
  119.     /*
  120.      * Load number 1.
  121.      */
  122.  
  123.     LoadVoice(1);
  124.  
  125.     /*
  126.      * Print the list of commands.
  127.      */
  128.  
  129.     printf("Speech Manager demo - by Alexander Kourakos - kourakos@ncsc.org\n");
  130.     PrintHelp();
  131.     }
  132.  
  133.  
  134. /*
  135.  * Read in a line. If it is a command, do it, otherwise, say it.
  136.  */
  137.  
  138. void ReadLine(void) {
  139.     char    string[255];
  140.     OSErr    err;
  141.     short    newVoiceIndex;
  142.     Fixed    aFixed;
  143.     long    aLong;
  144.  
  145.     printf("> ");
  146.     gets(string);
  147.  
  148.     /*
  149.      * Process a voice command.
  150.      */
  151.  
  152.     if( string[0] == 'v' ) {
  153.         if( string[1] == '?' ) {
  154.             printf("Current voice: %d (%s, ",gCurrentVoiceIndex,(char *)gVoiceDescription.name);
  155.             switch( gVoiceDescription.gender ) {
  156.                 case kNeuter:
  157.                     printf("neuter");
  158.                     break;
  159.                 case kMale:
  160.                     printf("male");
  161.                     break;
  162.                 case kFemale:
  163.                     printf("female");
  164.                     break;
  165.                 }
  166.             printf(", age %hd)\n\n",gVoiceDescription.age);
  167.             return;
  168.             }
  169.  
  170.         if( string[1] == ' ' ) {
  171.             sscanf(string,"%*s %d",&newVoiceIndex);
  172.             LoadVoice(newVoiceIndex);
  173.             return;
  174.             }
  175.         }
  176.  
  177.     /*
  178.      * Process a rate command.
  179.      */
  180.  
  181.     if( string[0] == 'r' ) {
  182.         if( string[1] == '?' ) {
  183.             err = GetSpeechRate(gSpeechChannel,&aFixed);
  184.             if( err != noErr) HandleError(err);
  185.  
  186.             printf("Current speech rate: %ld\n\n",Fix2Long(aFixed));
  187.             return;
  188.             }
  189.  
  190.         if( string[1] == ' ' ) {
  191.             sscanf(string + 2," %ld",&aLong);
  192.  
  193.             err = SetSpeechRate(gSpeechChannel,Long2Fix(aLong));
  194.             if( err != noErr) HandleError(err);
  195.             return;
  196.             }
  197.         }
  198.  
  199.     /*
  200.      * Process a pitch command.
  201.      */
  202.  
  203.     if( string[0] == 'p' ) {
  204.         if( string[1] == '?' ) {
  205.             err = GetSpeechPitch(gSpeechChannel,&aFixed);
  206.             if( err != noErr) HandleError(err);
  207.  
  208.             printf("Current pitch: %ld\n\n",Fix2Long(aFixed));
  209.             return;
  210.             }
  211.  
  212.         if( string[1] == ' ' ) {
  213.             sscanf(string + 2," %ld",&aLong);
  214.  
  215.             err = SetSpeechPitch(gSpeechChannel,Long2Fix(aLong));
  216.             if( err != noErr) HandleError(err);
  217.             return;
  218.             }
  219.         }
  220.  
  221.     /*
  222.      * Do they want help?
  223.      */
  224.  
  225.     if( !strcmp(string,"??") ) {
  226.         PrintHelp();
  227.         return;
  228.         }
  229.  
  230.     /*
  231.      * Do they want to quit?
  232.      */
  233.  
  234.     if( !strcmp(string,"quit") ) {
  235.         gDone = true;
  236.         return;
  237.         }
  238.  
  239.     /*
  240.      * If it isn't "!!", then copy the string into the string to speak.
  241.      */
  242.  
  243.     if( strcmp(string,"!!") ) {
  244.         strcpy(gSayThis,string);
  245.         }
  246.  
  247.     /*
  248.      * Stop speech on this channgel.
  249.      * (Is this necessary? Couldn't hurt...)
  250.      */
  251.  
  252.     err = StopSpeech(gSpeechChannel);
  253.     if( err != noErr) HandleError(err);
  254.  
  255.     /*
  256.      * Speak the text.
  257.      */
  258.  
  259.     err = SpeakText(gSpeechChannel,(Ptr)gSayThis,strlen(gSayThis));
  260.     if( err != noErr) HandleError(err);
  261.     }
  262.  
  263.  
  264. /*
  265.  * Loads in a voice with the given index, and sets the global variables appropriately.
  266.  */
  267.  
  268. void LoadVoice(short index) {
  269.     OSErr        err;
  270.     VoiceSpec    voiceSpec;
  271.  
  272.     err = GetIndVoice(index,&voiceSpec);
  273.     if( err != noErr) HandleError(err);
  274.  
  275.     /*
  276.      * Get the description and stash it in a global variable so other
  277.      * functions can get the info.
  278.      */
  279.  
  280.     err = GetVoiceDescription(&voiceSpec,&gVoiceDescription,sizeof(VoiceDescription));
  281.     if( err != noErr) HandleError(err);
  282.  
  283.     /*
  284.      * So we can print with ANSI routines...
  285.      */
  286.  
  287.     (void)PtoCstr((void *)gVoiceDescription.name);
  288.  
  289.     /*
  290.      * If there was an old channel, trash it.
  291.      */
  292.  
  293.     if( gSpeechChannel != nil ) {
  294.         err = DisposeSpeechChannel(gSpeechChannel);
  295.         if( err != noErr) HandleError(err);
  296.         }
  297.  
  298.     /*
  299.      * Create a new channel using this voice specification. I don't know if
  300.      * this is necessary, maybe I can just assign a new voice spec to the
  301.      * channel somehow.
  302.      */
  303.  
  304.     err = NewSpeechChannel(&voiceSpec,&gSpeechChannel);
  305.     if( err != noErr) HandleError(err);
  306.  
  307.     gCurrentVoiceIndex = index;
  308.     }
  309.  
  310.  
  311. /*
  312.  * Prints the commands.
  313.  */
  314.  
  315. void PrintHelp(void) {
  316.     printf("Commands are:\n");
  317.     printf("quit         - to quit\n");
  318.     printf("v?           - display current voice info\n");
  319.     printf("v <n>        - set current voice to <n> [1-%hd]\n",gCountVoices);
  320.     printf("r?           - display current speech rate\n");
  321.     printf("r <n>        - set speech rate to <n> [0 - 500]\n");
  322.     printf("p?           - display current pitch\n");
  323.     printf("p <n>        - set pitch to <n> [0 - 127]\n");
  324.     printf("!!           - repeat last phrase\n");
  325.     printf("??           - this list of commands\n");
  326.     printf("\n");
  327.     }
  328.  
  329.  
  330. /*
  331.  * Oops, something went wrong.
  332.  */
  333.  
  334. void HandleError(OSErr err) {
  335.     fprintf(stderr,"\a\n\nSorry, an error occurred: ");
  336.  
  337.     switch( err ) {
  338.  
  339.         /*
  340.          * The Speech Manager errors.
  341.          */
  342.  
  343.         case noSynthFound:
  344.             fprintf(stderr,"No synth found.\n");
  345.             break;
  346.         case synthOpenFailed:
  347.             fprintf(stderr,"Synth open failed.\n");
  348.             break;
  349.         case synthNotReady:
  350.             fprintf(stderr,"Synth not ready.\n");
  351.             break;
  352.         case bufTooSmall:
  353.             fprintf(stderr,"Buffer too small.\n");
  354.             break;
  355.         case voiceNotFound:
  356.             fprintf(stderr,"Voice not found.\n");
  357.             break;
  358.         case incompatibleVoice:
  359.             fprintf(stderr,"Incompatible voice.\n");
  360.             break;
  361.         case badDictFormat:
  362.             fprintf(stderr,"Bad dictionary format.\n");
  363.             break;
  364.         case badInputText:
  365.             fprintf(stderr,"Bad input text.\n");
  366.             break;
  367.  
  368.         /*
  369.          * Other errors that may occur.
  370.          */
  371.  
  372.         case gestaltUnknownErr:
  373.             fprintf(stderr,"Gestalt doesn't have a clue.\n");
  374.             break;
  375.         case gestaltUndefSelectorErr:
  376.             fprintf(stderr,"Unknown Gestalt selector.\n");
  377.             break;
  378.         case paramErr:
  379.             fprintf(stderr,"Parameter error.\n");
  380.             break;
  381.  
  382.         /*
  383.          * Default: print the number and quit.
  384.          */
  385.  
  386.         default:
  387.             fprintf(stderr,"Error %d.\n",(int)err);
  388.         }
  389.     exit(EXIT_FAILURE);
  390.     }
  391.  
  392.